/*
 * Copyright 2007. Mount Sinai Hospital, Toronto, Canada.
 * 
 * Licensed under the GNU Lesser General Public License, Version 2. You
 * can find a copy of the license at:
 * 
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 * 
 * IN NO EVENT SHALL MOUNT SINAI HOSPITAL BE LIABLE TO ANY PARTY FOR DIRECT, 
 * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST 
 * PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
 * EVEN IF MOUNT SINAI HOSPITAL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 
 * DAMAGE.
 * 
 * MOUNT SINAI HOSPITAL SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND 
 * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". 
 * MOUNT SINAI HOSPITAL HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
 * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 
 */
package com.sinai.mshab.client.ui.aggregate;

import java.util.ArrayList;

import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * This is a fancy extension to FlexTable that is designed to nealty represent
 * database queries in a table.
 * 
 * To populate this table with some information from the database, use the
 * Server's execteSQL(String sql, int start, int end) method.
 * 
 * Also, for the sake of formatting please use aliases in your custom sqls, ie:
 * SELECT Table1.field_one Table1_field_one, Table2.fie.....
 * 
 * @author serge
 * 
 */
public class TableComponent extends FlexTable {

	/**
	 * Boolean to keep track of whether or not first column should be linked.
	 */
	private boolean linkRow;

	/**
	 * The prefix that appears in the URL when the user clicks on a database
	 * record. The default value will be "record="
	 */
	private String historyChangePrefix = "record=";

	/**
	 * Creates a new table component
	 * 
	 * @param linkRow
	 *            specifies if first column should be linked to it's value via
	 *            history
	 */
	public TableComponent(boolean linkRow) {
		this.linkRow = linkRow;
	}

	/**
	 * Creates a new table component
	 * 
	 * @param linkRow
	 *            specifies if first column should be linked to it's value via
	 *            history
	 * @param historyChangePrefix
	 *            the prefix that appears in the URL when the user clicks on a
	 *            database record.
	 */
	public TableComponent(boolean linkRow, String historyChangePrefix) {
		this.linkRow = linkRow;
		this.historyChangePrefix = historyChangePrefix;
	}

	/**
	 * Retreives the right information from the database and populates table
	 * with it.
	 * 
	 * @param rows
	 *            the arraylist of rows containg array lists of columns
	 *            containing this tables data.
	 */
	public void populate(ArrayList rows) {

		setStyleName("advanced_search_table");
		setCellSpacing(0);

		int number_of_cols = 0;

		// if we got back our column headers
		if (rows.size() > 1) {
			ArrayList cols = (ArrayList) rows.get(1);
			number_of_cols = cols.size();
			for (int i = 0; i < cols.size(); i++) {
				String name = (String) cols.get(i);

				// extract table name
				if (name.length() > 0 && name.indexOf('_') != -1) {

					// preparing formatting of table name
					String table_name = name.substring(0, name.indexOf('_'));
					if (table_name.length() > 10) {
						table_name = table_name.substring(0, 10);
						table_name = table_name + "..";
					}
					table_name = "(" + table_name + ")";

					// preparing formatting of field name
					String field_name = name.substring(name.indexOf('_'), name
							.length());
					field_name = field_name.replace('_', ' ');
					field_name.trim();

					// putting the two labels together.
					VerticalPanel vpanel = new VerticalPanel();
					Label field_name_label = new Label(field_name);
					Label table_name_label = new Label(table_name);
					field_name_label.setStyleName("advanced_field_name");
					table_name_label.setStyleName("advanced_table_name");
					vpanel.add(field_name_label);
					vpanel.add(table_name_label);
					setWidget(0, i, vpanel);

				} else {
					// not sure what's going on, just put the name given to us
					// by sql.
					setWidget(0, i, new Label(name.replace('_', ' ')));
				}
			}
		}

		// if we got back some data
		if (rows.size() > 2) {
			
			for (int i = 2; i < rows.size(); i++) {

				ArrayList cols = (ArrayList) rows.get(i);
				
				// assume that the first column is the Key
				// TODO: avoid this assumption.
				String key = (String) cols.get(0);
				for (int j = 0; j < cols.size(); j++) {
					String name = (String) cols.get(j);
					
					// make each column a hyperlink to a report based on the key
					if (linkRow) {
						Hyperlink link = new Hyperlink(name,
								historyChangePrefix + key);
						link.setStyleName("advanced_link");
						setWidget(i, j, link);
					} else {
						setWidget(i, j, new Label(name));
					}
				}

			}
		}

		RowFormatter rowFormatter = getRowFormatter();
		for (int rowIndex = 1; rowIndex < getRowCount(); rowIndex++) {
			if (rowIndex % 2 == 0) {
				rowFormatter.setStyleName(rowIndex, "customRowStyle");
			} else {
				rowFormatter.setStyleName(rowIndex, "tableRow");
			}
		}

		// Set Style Name for the header
		rowFormatter.setStyleName(0, "advanced_search_table_header");

		// Set the Styles for the Data Rows and Columns
		CellFormatter cellFormatter = getCellFormatter();

		// Set the styles for the headers
		for (int colIndex = 0; colIndex < number_of_cols; colIndex++) {
			cellFormatter.setStyleName(0, colIndex,
					"advanced_search_table_header_text");
			cellFormatter.setAlignment(0, colIndex,
					HasHorizontalAlignment.ALIGN_CENTER,
					HasVerticalAlignment.ALIGN_MIDDLE);
		}
	}
}
